package tech.aistar.corejava.day05;

import java.util.Arrays;

/**
 *  业务场景:一个学生只能属于一个班级中.
 * 实体类
 * @author success
 * @version 1.0
 * @description:本类用来演示:学生实体类
 * @date 2019/7/19 0019
 */
public class Student {
    //分析学生对象拥有的属性

    //修饰符 数据类型 属性名 [ = 初始值];

    //属性是基本数据类型
    private int id;

    //属性可以是对象类型 - String
    private String sno;

    private String sname;//学生的名称

    //public int age;

    //私有化属性
    private int age;

    //数组
    private String[] hobbies;

    //对象与对象的关系
    //数据类型可以是自定义对象类型
    private Clazz clazz;

    //---------------构造-------------

    /**
     *  如果这个类中没有提供任何的一个构造的时候,那么系统会默认分配
	 *  空参构造
     *
     *  如果一旦类中提供了构造,那么系统将不会再分配一个默认构造
     */
    public Student(){
        System.out.println("空参构造被调用了!");
    }

    /**
     * 两参构造
     * @param sid
     * @param name
     */
   // public Student(int sid,String name){
       // System.out.println("带参构造被调用了...");
        //System.out.println("id:"+id);
        //System.out.println("sname:"+sname);

        //可以出在构造方法中可以使用非静态成员[非静态属性]
        //JVM加载类进内存的时候
        //优先加载的所有的静态的成员[分配空间以及初始化]
        //当创建对象的时候 Student s = new Student(10,"tom");
        //会优先给所有的非静态成员分配空间以及初始化
        //然后才是去调用构造方法["肉眼能看到的"]
      //  id = sid;
       // sname = name;
   // }

    /**
     *
     * @param id
     * @param sname
     */
    public Student(int id,String sname){
        //this();//去调用本类中已经存在的空参构造.
        System.out.println("两参构造被调用了...");
        //System.out.println("this:"+this);//创建出来的那个对象,当前对象.
        this.id = id;
        //this.sname = sname;
        //调用setter方法来对参数有效性进行判断
        setSname(sname);
    }

    /**
     * 三参构造
     * @param id
     * @param sno
     * @param sname
     */
    public Student(int id,String sno,String sname){
        this(id,sname);//调用当前的两参构造
        System.out.println("三参构造...");
        //this.id = id;
        //this.sname = sname;
        this.sno = sno;
    }

    /**
     * 每个属性都应该提供一个setter方法
     * 并且setter方法的推荐的命名一定是set+属性名[首字母变大写]   -  why? - 学习框架 - 反射技术
     * @param id
     */
    public void setId(int id){
        this.id = id;
    }

    public void setSname(String sname) {
        //字符串的比较使用java.lang.String类中提供的equals方法
        //setter方法可以对参数进行有效性判断
        if("cnm".equals(sname)){
            this.sname = "***";

            //当void中出现return语句的时候,那么代表结束整个方法
            return;
        }
        this.sname = sname;
    }

    public String getSname(){
        return sname;
    }

    public int getId() {
        return id;
    }

    public String getSno() {
        return sno;
    }

    public void setSno(String sno) {
        this.sno = sno;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String[] getHobbies() {
        return hobbies;
    }

    public void setHobbies(String[] hobbies) {
        this.hobbies = hobbies;
    }

    public Clazz getClazz() {
        return clazz;
    }

    public void setClazz(Clazz clazz) {
        this.clazz = clazz;
    }

    /**
     * 重写父类java.lang.Object中的toString方法
     * 为什么要重写父类中的toString方法 - 它不满足我需要打印的需求[默认的是内存地址]
     *
     * 只要子类中重写了父类中的方法,那么使用子类对象调用方法的时候,默认采取的是
     * "就近原则" - 调用自己当中重写之后的方法
     * @return
     */

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("Student{");
        sb.append("id=").append(id);
        sb.append(", sno='").append(sno).append('\'');
        sb.append(", sname='").append(sname).append('\'');
        sb.append(", age=").append(age);
        sb.append(", hobbies=").append(Arrays.toString(hobbies));
<<<<<<< HEAD
        sb.append(", Clazz=").append(clazz.toString());
=======
        sb.append(", clazz=").append(clazz.toString());
>>>>>>> d27e1de945c2c60c709234beeb7186387809e6da
        sb.append('}');
        return sb.toString();
    }
}
